/******************************************************************************
//             INTEL CORPORATION PROPRIETARY INFORMATION
//  This software is supplied under the terms of a license agreement or
//  nondisclosure agreement with Intel Corporation and may not be copied
//  or disclosed except in accordance with the terms of that agreement.
//        Copyright (c) 2000-2001 Intel Corporation. All Rights Reserved.
//
//  Description:
//      Intel(R) JPEG library for X platform 
//
********************************************************************************/
#include "_ijx.h"

extern const Ipp8u _nIZigZagIndex[64];

/******************************************************************************
// Name:            ijDecodeScanData_Motion
// Description:     Decoding scan data for Motion mode
// Input Arguments:
//         pStream: Identifies IJBITTREAMSTATE data structure.
//    pDecodeState: Identifies IJDECODESTATE strcuture.
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/
IJXRESULT ijDecodeScanData_Motion( IJBITTREAMSTATE  *pStream,
                                   IJDECODESTATE    *pDecodeState)
{
    int x, y;

    int nHMCUPos, nVMCUPos;
    int nHMCUCount, nVMCUCount;
    int nMCUWidth, nMCUHeight;
    int nMCUPadWidth, nMCUPadHeight;
    int nImageMCUHOffset, nImageMCUVOffset;

    int nTempImageStep;
    int nProcessedBitsLen;
    Ipp16s **ppCoeffBuf;
    Ipp16s **ppMCUBuf;
    Ipp8u  *pTempImageData;
    Ipp8u  *pImageCur;

    Ipp8u *pImageData;
    int   nImageStep;

    IppiSize dstSize;

    IJBUFFER *pIJXBuffer;
    IJMCUSPEC *pMCUSpec;
    IIPIMAGESPEC *pImageSpec;
    IJDEPROCESSSPEC *pProcSpec;

//    IJX_ASSERT(NULL!=pIJXBuffer);
//    IJX_ASSERT(NULL!=pStream);
//    IJX_ASSERT(NULL!=pDecodeState);

    pIJXBuffer=&(pDecodeState->bufSpec);
    pMCUSpec=&(pDecodeState->mcuSpec);
    pImageSpec=&(pDecodeState->imageSpec);
    pProcSpec=&(pDecodeState->procSpec);

    pImageData=pIJXBuffer->paImageBufCur[0];
    nImageStep=pIJXBuffer->naImageStep[0];

    nHMCUPos=pDecodeState->nHMCUCurPos;
    nVMCUPos=pDecodeState->nVMCUCurPos;
    nHMCUCount=pMCUSpec->nHMCUCount;
    nVMCUCount=pMCUSpec->nVMCUCount;
    nMCUWidth=pMCUSpec->nMCUWidth;
    nMCUHeight=pMCUSpec->nMCUHeight;
    nMCUPadWidth=pMCUSpec->nMCUPadWidth;
    nMCUPadHeight=pMCUSpec->nMCUPadHeight;

    nImageMCUHOffset=((pImageSpec->nBitsPerpixel)>>3)*nMCUWidth;
    nImageMCUVOffset=nImageStep*nMCUHeight;

    ppCoeffBuf=(Ipp16s **)(pIJXBuffer->paImgCoeffBufCur);
    ppMCUBuf =(Ipp16s **)(pIJXBuffer->paMCUCoeffBufCur);

    nTempImageStep=pMCUSpec->nImageMCUStep;
    pTempImageData=pIJXBuffer->pAuxMCUDataTempBuf;

    nProcessedBitsLen=pStream->nUsedBufBitsLen;

    for (y=nVMCUPos; y<nVMCUCount; y++) {
        pImageCur=pImageData;
        for (x=nHMCUPos; x<nHMCUCount; x++) {
            pProcSpec->funcHuffmanDecoder( (const Ipp16s **)ppCoeffBuf, pStream, pDecodeState);
            pProcSpec->funcMCUTransform((const Ipp16s **)ppCoeffBuf, ppMCUBuf, 
                                        (const Ipp32s **)(pDecodeState->paIdxDCTDequantTable));
            pProcSpec->funcMCUColorConvert((const Ipp16s **)ppMCUBuf, pImageCur, nImageStep);

            pImageCur+=nImageMCUHOffset;
        } //for (x=nHMCUPos; x<nHMCUCount; x++) 

        if (0<nMCUPadWidth) {
            dstSize.width=nMCUPadWidth;
            dstSize.height=nMCUHeight;

            pProcSpec->funcHuffmanDecoder((const Ipp16s **)ppCoeffBuf, pStream, pDecodeState);
            pProcSpec->funcMCUTransform((const Ipp16s **)ppCoeffBuf, ppMCUBuf,
                                        (const Ipp32s **)(pDecodeState->paIdxDCTDequantTable));
            pProcSpec->funcMCUColorConvert((const Ipp16s **)ppMCUBuf, pTempImageData, nTempImageStep);
            pProcSpec->funcCopyROI(pTempImageData, nTempImageStep, pImageCur, nImageStep, dstSize);

        }//if (0<nMCUPadWidth)
        pImageData+=nImageMCUVOffset;
    } //for (y=nVMCUPos; y<nVMCUCount; y++)

    if (0<nMCUPadHeight) {
        dstSize.width=nMCUWidth;
        dstSize.height=nMCUPadHeight;
        for (x=nHMCUPos; x<nHMCUCount; x++) {
            pProcSpec->funcHuffmanDecoder((const Ipp16s **)ppCoeffBuf, pStream, pDecodeState);
            pProcSpec->funcMCUTransform((const Ipp16s **)ppCoeffBuf, ppMCUBuf,
                                        (const Ipp32s **)(pDecodeState->paIdxDCTDequantTable));
            pProcSpec->funcMCUColorConvert((const Ipp16s **)ppMCUBuf, pTempImageData, nTempImageStep);
            pProcSpec->funcCopyROI(pTempImageData, nTempImageStep, pImageData, nImageStep, dstSize);

            pImageData+=nImageMCUHOffset;
        } //for (x=nHMCUPos; x<nHMCUCount; x++)
        if (0<nMCUPadWidth) {
            dstSize.width=nMCUPadWidth;
            pProcSpec->funcHuffmanDecoder((const Ipp16s **)ppCoeffBuf, pStream, pDecodeState);
            pProcSpec->funcMCUTransform((const Ipp16s **)ppCoeffBuf, ppMCUBuf,
                                        (const Ipp32s **)(pDecodeState->paIdxDCTDequantTable));
            pProcSpec->funcMCUColorConvert((const Ipp16s **)ppMCUBuf, pTempImageData, nTempImageStep);
            pProcSpec->funcCopyROI(pTempImageData, nTempImageStep, pImageData, nImageStep, dstSize);
        } //if (0<nMCUPadWidth)
    } //if (0<nMCUPadHeight)

    //pDecodeState->nHMCUCurPos=x;
    //pDecodeState->nVMCUCurPos=y;
    nProcessedBitsLen=pStream->nUsedBufBitsLen-nProcessedBitsLen;
    pDecodeState->counter.nProcessedBitsLen+=nProcessedBitsLen;

    return IJX_RTCODE_OK;
}


/******************************************************************************
// Name:            ijDecodeScanData_Motion_Diff
// Description:     Not support in this version
// Input Arguments:
// Output Arguments:
//                          
// Returns:          
//        [Success] IJX_RTCODE_OK
//        [Failure] IJX_RTCODE_BAGARG
//                  IJX_RTCODE_INSUFFICIENTBUF
//                  IJX_RTCODE_ERRPARSE
//                     
//                  
******************************************************************************/

///////////////////////////////////////
#ifdef _MOTION_DIFF

IJXRESULT ijDecodeScanData_Motion_Diff(Ipp8u *pImageData,
                                       int   nImageStep,
                                       IJBUFFER *pIJXBuffer,
                                       IJBITTREAMSTATE  *pStream,
                                       IJDECODESTATE    *pDecodeState)
{
    int x, y;

    int nHMCUPos, nVMCUPos;
    int nHMCUCount, nVMCUCount;
    int nMCUWidth, nMCUHeight;
    int nMCUPadWidth, nMCUPadHeight;
    int nImageMCUHOffset, nImageMCUVOffset;

    int nTempImageStep;
    int nProcessedBitsLen;
    //Ipp16s **ppMCUBuf;
    Ipp8u  *pTempImageData;
    Ipp8u  *pImageCur;

    IppiSize dstSize;


    IJMCUSPEC *pMCUSpec;
    IIPIMAGESPEC *pImageSpec;
    IJDEPROCESSSPEC *pProcSpec;

    pMCUSpec=&(pDecodeState->mcuSpec);
    pImageSpec=&(pDecodeState->imageSpec);
    pProcSpec=&(pDecodeState->procSpec);

    nHMCUPos=pDecodeState->nHMCUCurPos;
    nVMCUPos=pDecodeState->nVMCUCurPos;
    nHMCUCount=pMCUSpec->nHMCUCount;
    nVMCUCount=pMCUSpec->nVMCUCount;
    nMCUWidth=pMCUSpec->nMCUWidth;
    nMCUHeight=pMCUSpec->nMCUHeight;
    nMCUPadWidth=pMCUSpec->nMCUPadWidth;
    nMCUPadHeight=pMCUSpec->nMCUPadHeight;

    nImageMCUHOffset=((pImageSpec->nBitsPerpixel)>>3)*nMCUWidth;
    nImageMCUVOffset=nImageStep*nMCUHeight;

    //ppMCUBuf =(Ipp16s **)(pIJXBuffer->paMCUBufCur);

    nTempImageStep=pMCUSpec->nImageMCUStep;
    pTempImageData=(Ipp8u *)IIP_ALIGN_32B(pIJXBuffer->pAUXBuffer);

    nProcessedBitsLen=pStream->nUsedBufBitsLen;

    for (y=nVMCUPos; y<nVMCUCount; y++) {
        pImageCur=pImageData;
        for (x=nHMCUPos; x<nHMCUCount; x++) {
            pProcSpec->funcMotionDiffDecoder(pIJXBuffer, pStream, pDecodeState);
            pProcSpec->funcMCUColorConvert((const Ipp16s **)(pIJXBuffer->paCoeffBufCur), 
                                           pImageCur, nImageStep);

            pImageCur+=nImageMCUHOffset;
            pProcSpec->funcAdjustMCUBuf(pMCUSpec, pIJXBuffer);

            pDecodeState->counter.nScanMCUCounter++;
            if ( (0<pDecodeState->nRstInterval) ){
                pDecodeState->counter.nDRICounter--;
                if (0==pDecodeState->counter.nDRICounter) {
                    ijAdjustRestartIntervalInv(pStream, pDecodeState);
                }
            }
        } //for (x=nHMCUPos; x<nHMCUCount; x++) 

        if (0<nMCUPadWidth) {
            dstSize.width=nMCUPadWidth;
            dstSize.height=nMCUHeight;
            pProcSpec->funcMotionDiffDecoder(pIJXBuffer, pStream, pDecodeState);
            pProcSpec->funcMCUColorConvert((const Ipp16s **)(pIJXBuffer->paCoeffBufCur), 
                                           pTempImageData, nTempImageStep);
            pProcSpec->funcCopyROI(pTempImageData, nTempImageStep, pImageCur, nImageStep, dstSize);
            pProcSpec->funcAdjustMCUBuf(pMCUSpec, pIJXBuffer);

            pDecodeState->counter.nScanMCUCounter++;
            if ( (0<pDecodeState->nRstInterval) ){
                pDecodeState->counter.nDRICounter--;
                if (0==pDecodeState->counter.nDRICounter) {
                    ijAdjustRestartIntervalInv(pStream, pDecodeState);
                }
            }
        }//if (0<nMCUPadWidth)
        pImageData+=nImageMCUVOffset;
    } //for (y=nVMCUPos; y<nVMCUCount; y++)

    if (0<nMCUPadHeight) {
        dstSize.width=nMCUWidth;
        dstSize.height=nMCUPadHeight;
        for (x=nHMCUPos; x<nHMCUCount; x++) {
            pProcSpec->funcMotionDiffDecoder(pIJXBuffer, pStream, pDecodeState);
            pProcSpec->funcMCUColorConvert((const Ipp16s **)(pIJXBuffer->paCoeffBufCur), 
                                           pTempImageData, nTempImageStep);
            pProcSpec->funcCopyROI(pTempImageData, nTempImageStep, pImageData, nImageStep, dstSize);

            pImageData+=nImageMCUHOffset;
            pProcSpec->funcAdjustMCUBuf(pMCUSpec, pIJXBuffer);

            pDecodeState->counter.nScanMCUCounter++;
            if ( (0<pDecodeState->nRstInterval) ){
                pDecodeState->counter.nDRICounter--;
                if (0==pDecodeState->counter.nDRICounter) {
                    ijAdjustRestartIntervalInv(pStream, pDecodeState);
                }
            }
        } //for (x=nHMCUPos; x<nHMCUCount; x++)
        if (0<nMCUPadWidth) {
            dstSize.width=nMCUPadWidth;
            pProcSpec->funcMotionDiffDecoder(pIJXBuffer, pStream, pDecodeState);
            pProcSpec->funcMCUColorConvert((const Ipp16s **)(pIJXBuffer->paCoeffBufCur), 
                                           pTempImageData, nTempImageStep);
            pProcSpec->funcCopyROI(pTempImageData, nTempImageStep, pImageData, nImageStep, dstSize);

            pDecodeState->counter.nScanMCUCounter++;
            if ( (0<pDecodeState->nRstInterval) ){
                pDecodeState->counter.nDRICounter--;
                if (0==pDecodeState->counter.nDRICounter) {
                    ijAdjustRestartIntervalInv(pStream, pDecodeState);
                }
            }
        } //if (0<nMCUPadWidth)
    } //if (0<nMCUPadHeight)

    //pDecodeState->nHMCUCurPos=x;
    //pDecodeState->nVMCUCurPos=y;
    ijResetBuffers(pIJXBuffer);
    nProcessedBitsLen=pStream->nUsedBufBitsLen-nProcessedBitsLen;
    pDecodeState->counter.nProcessedBitsLen+=nProcessedBitsLen;

    return IJX_RTCODE_OK;
}

#endif
///////////////////////////////////////

/* EOF */
